package com.gcloud.controller.network.dao;

import com.gcloud.common.util.StringUtils;
import com.gcloud.controller.network.entity.Subnet;
import com.gcloud.controller.network.enums.NetworkType;
import com.gcloud.controller.network.model.DescribeSubnetParams;
import com.gcloud.controller.network.model.DescribeVSwitchesParams;
import com.gcloud.core.currentUser.policy.enums.ResourceIsolationCheckType;
import com.gcloud.core.currentUser.policy.enums.UserResourceFilterPolicy;
import com.gcloud.core.currentUser.policy.model.FilterPolicyModel;
import com.gcloud.core.currentUser.policy.service.IUserResourceFilterPolicy;
import com.gcloud.core.service.SpringUtil;
import com.gcloud.framework.db.PageResult;
import com.gcloud.framework.db.dao.impl.JdbcBaseDaoImpl;
import com.gcloud.header.api.model.CurrentUser;
import com.gcloud.header.compute.enums.DeviceOwner;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;
/**
Copyright (c) [2020] [G-CLOUD TECHNOLOGY] [G-Cloud 8.0] is licensed under the Mulan PSL v1.
You can use this software according to the terms and conditions of the Mulan PSL v1. You may obtain
a copy of Mulan PSL v1 at: http://license.coscl.org.cn/MulanPSL THIS SOFTWARE IS PROVIDED ON AN 
"AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. See the Mulan PSL v1 for more details.
 */
@Repository
public class SubnetDao extends JdbcBaseDaoImpl<Subnet, String> {
	public <E> PageResult<E> describeVSwitches(DescribeVSwitchesParams params, Class<E> clazz, CurrentUser currentUser){
		IUserResourceFilterPolicy filterPolicy = (IUserResourceFilterPolicy)SpringUtil.getBean(UserResourceFilterPolicy.TYPICAL.getFilterPolicyClazz());
		FilterPolicyModel sqlModel = filterPolicy.filterPolicy(currentUser, "s.", ResourceIsolationCheckType.SUBNET);
		
		StringBuffer sql = new StringBuffer();
		List<Object> listParams = new ArrayList<Object>();

//        sql.append("select s.id as vSwitchId,s.network_id as vpcId,s.cidr as cidrBlock,s.name as vSwitchName,s.zone_id as zoneId,s.router_id as vRouterId from gc_subnets s");
        sql.append("select s.*, rs.router_id, gz.name as zoneName from gc_subnets s");
        if(params.getVpcId() != null && StringUtils.isNotBlank(params.getVpcId())) {
        	sql.append(" left join gc_networks n on s.network_id = n.id");
        }
        sql.append(" left join");
        sql.append(" (select group_concat(rp.router_id) router_id, i.subnet_id from gc_router_ports rp ");
        sql.append(" left join gc_ports p on rp.port_id = p.id left join gc_ipallocations i on p.id = i.port_id");
        sql.append(" where rp.port_type in(?, ?) group by i.subnet_id) rs");
        sql.append(" on s.id = rs.subnet_id");
        //联立gc_zones表，获取zoneName
        sql.append(" left join gc_zones as gz on s.zone_id = gz.id ");
        sql.append(" where 1=1");

        listParams.add(DeviceOwner.ROUTER.getValue());
        listParams.add(DeviceOwner.HA_ROUTER.getValue());

        if(params.getVpcId() != null && StringUtils.isNotBlank(params.getVpcId())) {
            sql.append(" and rs.router_id = ?");
            listParams.add(params.getVpcId());
            
            sql.append(" and n.type = ?");
            listParams.add(NetworkType.INTERNAL.getValue());
        }
        if(params.getNetworkId() != null && StringUtils.isNotBlank(params.getNetworkId())) {
            sql.append(" and s.network_id = ?");
            listParams.add(params.getNetworkId());
        }
        if(params.getvSwitchId() != null && StringUtils.isNotBlank(params.getvSwitchId())) {
        	sql.append(" and s.id = ?");
        	listParams.add(params.getvSwitchId());
        }
        
        sql.append(sqlModel.getWhereSql());
        listParams.addAll(sqlModel.getParams());
        
        sql.append(" order by s.create_time desc");

        return findBySql(sql.toString(),listParams, params.getPageNumber(), params.getPageSize(), clazz);
	}

	public List<Subnet> routerSubnet(String routerId){

	    StringBuffer sb = new StringBuffer();
	    sb.append("select * from gc_subnets s where s.id in(");
        sb.append(" select i.subnet_id from gc_router_ports rp ");
        sb.append(" left join gc_ports p on rp.port_id = p.id left join gc_ipallocations i on p.id = i.port_id");
        sb.append(" where rp.router_id = ?");
	    sb.append(")");

	    List<Object> values = new ArrayList<>();
	    values.add(routerId);
	    return findBySql(sb.toString(), values);
    }

	public boolean hasSubnet(String networkId){
	    List<Object> values = new ArrayList<>();

	    String sql = "select * from gc_subnets t where t.network_id = ? limit 1";
        values.add(networkId);
        List<Subnet> subnets = findBySql(sql, values);
        return subnets != null && subnets.size() > 0;

    }
	
	public <E>PageResult<E> describeSubnets(DescribeSubnetParams params, Class<E> clazz, CurrentUser currentUser) {
		/*IUserResourceFilterPolicy filterPolicy = (IUserResourceFilterPolicy)SpringUtil.getBean(UserResourceFilterPolicy.TYPICAL.getFilterPolicyClazz());
		FilterPolicyModel sqlModel = filterPolicy.filterPolicy(currentUser, "s.", ResourceIsolationType.ALL_TENANT);*/
		
		StringBuffer sql = new StringBuffer();
		List<Object> values = new ArrayList<>();
		
		sql.append("select s.*, z.name as zoneName from gc_subnets as s");
		sql.append(" left join gc_zones as z on s.zone_id = z.id");
		sql.append(" left join gc_networks as gn on s.network_id = gn.id");
		sql.append(" where 1 = 1");
		
		//添加子网ID过滤
		if(StringUtils.isNotBlank(params.getSubnetId())) {
			sql.append(" and s.id = ?");
			values.add(params.getSubnetId());
		}
		
		if(StringUtils.isNotBlank(params.getNetworkId())) {
			sql.append(" and s.network_id = ?");
			values.add(params.getNetworkId());
		}
		
		if(null != params.getNetworkType()) {
			sql.append(" and gn.type = ?");
			values.add(params.getNetworkType());
		}
		
		
		/*sql.append(sqlModel.getWhereSql());
		values.addAll(sqlModel.getParams());*/
		
		return findBySql(sql.toString(), values, params.getPageNumber(), params.getPageSize(), clazz);
	}
	
	public <E> List<E> getVSwitchs(Class<E> clazz, CurrentUser currentUser){
		IUserResourceFilterPolicy filterPolicy = (IUserResourceFilterPolicy)SpringUtil.getBean(UserResourceFilterPolicy.TYPICAL.getFilterPolicyClazz());
		FilterPolicyModel sqlModel = filterPolicy.filterPolicy(currentUser, "s.", ResourceIsolationCheckType.SUBNET);
		
		StringBuffer sql = new StringBuffer();
		List<Object> listParams = new ArrayList<Object>();
		sql.append("select * from gc_subnets s where 1=1 ");
		
		sql.append(sqlModel.getWhereSql());
        listParams.addAll(sqlModel.getParams());
        
        return findBySql(sql.toString(),listParams, clazz);
	}
}